package com.hlf.modules.sys.service.impl;

import com.hlf.common.constants.Constants;
import com.hlf.common.exception.BusinessException;
import com.hlf.common.utils.*;
import com.hlf.common.validator.Assert;
import com.hlf.modules.api.entity.UserStore;
import com.hlf.modules.api.mapper.UserStoreMapper;
import com.hlf.modules.api.service.SMSService;
import com.hlf.modules.merchant.merchant.entity.Merchant;
import com.hlf.modules.merchant.merchant.mapper.MerchantMapper;
import com.hlf.modules.sys.entity.SysUserEntity;
import com.hlf.modules.sys.mapper.SysUserMapper;
import com.hlf.modules.sys.service.SysRoleService;
import com.hlf.modules.sys.service.SysUserRoleService;
import com.hlf.modules.sys.service.SysUserService;
import com.hlf.modules.sys.service.SysUserTokenService;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;


/**
 * 系统用户
 *
 * @author chenshun
 * @email sunlightcs@gmail.com
 * @date 2016年9月18日 上午9:46:09
 */
@Service("sysUserService")
public class SysUserServiceImpl implements SysUserService {
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private SysUserRoleService sysUserRoleService;
    @Autowired
    private SysRoleService sysRoleService;
    @Autowired
    private MerchantMapper merchantMapper;
    @Autowired
    private SMSService sMSService;
    @Autowired
    private SysUserTokenService sysUserTokenService;
    @Autowired
    private UserStoreMapper userStoreMapper;


    @Override
    public List<String> queryAllPerms(Long userId) {
        return sysUserMapper.queryAllPerms(userId);
    }

    @Override
    public List<Long> queryAllMenuId(Long userId) {
        return sysUserMapper.queryAllMenuId(userId);
    }

    @Override
    public SysUserEntity queryByUserName(String username) {
        return sysUserMapper.queryByUserName(username);
    }

    @Override
    public SysUserEntity queryObject(Long userId) {
        return sysUserMapper.queryObject(userId);
    }

    @Override
    public List<SysUserEntity> queryList(Map<String, Object> map) {
        return sysUserMapper.queryList(map);
    }

    @Override
    public int queryTotal(Map<String, Object> map) {
        return sysUserMapper.queryTotal(map);
    }

    @Override
    @Transactional
    public void save(SysUserEntity user) {
        user.setCreateTime(new Date());
        //sha256加密
        String salt = RandomStringUtils.randomAlphanumeric(20);
        user.setPassword(new Sha256Hash(user.getPassword(), salt).toHex());
        user.setSalt(salt);
        sysUserMapper.save(user);
        //检查角色是否越权
        checkRole(user);

        //保存用户与角色关系
        sysUserRoleService.saveOrUpdate(user.getUserId(), user.getRoleIdList());
    }

    @Override
    @Transactional
    public void update(SysUserEntity user) {
        if (StringUtils.isBlank(user.getPassword())) {
            user.setPassword(null);
        } else {
            user.setPassword(new Sha256Hash(user.getPassword(), user.getSalt()).toHex());
        }
        sysUserMapper.update(user);

        //检查角色是否越权
        checkRole(user);

        //保存用户与角色关系
        sysUserRoleService.saveOrUpdate(user.getUserId(), user.getRoleIdList());
    }

    @Override
    @Transactional
    public void deleteBatch(Long[] userId) {
        sysUserMapper.deleteBatch(userId);
    }

    @Override
    public int updatePassword(Long userId, String password, String newPassword) {
        Map<String, Object> map = new HashMap<>();
        map.put("userId", userId);
        map.put("password", password);
        map.put("newPassword", newPassword);
        return sysUserMapper.updatePassword(map);
    }

    /**
     * 检查角色是否越权
     */
    private void checkRole(SysUserEntity user) {
        //如果不是超级管理员，则需要判断用户的角色是否自己创建
        if (user.getCreateUserId() == Constant.SUPER_ADMIN) {
            return;
        }

        //查询用户创建的角色列表
        List<Long> roleIdList = sysRoleService.queryRoleIdList(user.getCreateUserId());

        //判断是否越权
        if (!roleIdList.containsAll(user.getRoleIdList())) {
            throw new BusinessException("新增用户所选角色，不是本人创建");
        }
    }

    /**
     * 保存用户和商家信息
     *
     * @param mobile
     * @param password
     * @param name
     * @param identifyCode
     */
    @Transactional
    @Override
    public Map<String, Object> saveUserAndMerchant(String mobile, String password, String name, String identifyCode) {

        Integer j = mobileCount(mobile);
        if (j > 1) {
            throw new BusinessException("用户已经注册!");
        }

        boolean flag = sMSService.checkAuthCode(mobile, identifyCode, Constants.MESSAGE_TYPE_REGISTER);
        if (!flag) {
            throw new BusinessException("验证码验证失败!");
        }

        SysUserEntity user = new SysUserEntity();
        user.setMobile(mobile);
        user.setUsername(mobile);
        user.setName(name);
        user.setPassword(password);
        user.setCreateTime(new Date());
        sysUserMapper.insertSelective(user);

        Long userId = sysUserMapper.selectByMobile(mobile).getUserId();
        Merchant merchant = new Merchant();
        merchant.setId(IdWorkerFactory.nextId());
        merchant.setUserId(userId);
        merchant.setContactPhone(mobile);
        int i = merchantMapper.insertSelective(merchant);
        if (i == 0) {
            throw new BusinessException("注册失败,请联系管理员!");
        }
        List<Long> list = new ArrayList(1);
        list.add(Constants.ROLE_ID_MERCHANT);
        sysUserRoleService.saveOrUpdate(userId, list);
        SysUserEntity sysUserEntity = queryByUserName(mobile);
        Map<String, Object> map = sysUserTokenService.createToken(sysUserEntity.getUserId());
        map.put("merchantId", merchant.getId());
        return map;
    }

    /**
     * 忘记密码
     *
     * @param mobile
     * @param password
     * @return
     */
    @Override
    @Transactional
    public Integer forgetPassword(String mobile, String password, String identifyCode) {

        SysUserEntity sysUserEntity = sysUserMapper.selectByMobile(mobile);
        if (sysUserEntity == null) {
            throw new BusinessException("手机号不存在!");
        }

        boolean flag = sMSService.checkAuthCode(mobile, identifyCode, Constants.MESSAGE_TYPE_FIND);
        if (!flag) {
            throw new BusinessException("验证码验证失败!");
        }

        //sha256加密
        String salt = RandomStringUtils.randomAlphanumeric(20);
        sysUserEntity.setSalt(salt);
        sysUserEntity.setPassword(new Sha256Hash(password, salt).toHex());
        Integer i = sysUserMapper.updateByPrimaryKeySelective(sysUserEntity);
        return i;
    }

    /**
     * 查询手机号存在个数
     *
     * @param mobile
     * @return
     */
    @Override
    public Integer mobileCount(String mobile) {
        return sysUserMapper.selectCountByMobile(mobile);
    }

    /**
     * app登陆
     *
     * @param mobile
     * @param password
     * @return
     */
    @Override
    public SysUserEntity login(String mobile, String password) {
        SysUserEntity user = sysUserMapper.selectByMobile(mobile);
        Assert.isNull(user, "手机号或密码错误");

        //密码错误
        if (!user.getPassword().equals(password)) {
            throw new BusinessException("手机号或密码错误");
        }

        return user;
    }

    /**
     * 修改密码
     *
     * @param user
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updatep(SysUserEntity user, String oPassword, String nPassword) {
        String salt = RandomStringUtils.randomAlphanumeric(20);
        String oP = new Sha256Hash(oPassword, user.getSalt()).toHex();
        if (user == null || !user.getPassword().equals(oP)) {
            throw new BusinessException("原始密码不正确!");
        } else {
            String nP = new Sha256Hash(nPassword, salt).toHex();
            user.setPassword(nP);
            user.setSalt(salt);
            int i = sysUserMapper.updateByPrimaryKeySelective(user);
            if (i == 0) {
                throw new BusinessException("密码修改失败!");
            }
        }
    }

    /**
     * 查询用户列表
     *
     * @param currentStoreId
     * @return
     */
    @Override
    public List<SysUserEntity> queryListByStoreId(String currentStoreId) {
        return sysUserMapper.queryListByStoreId(currentStoreId);

    }

    /**
     * 新建管理员
     *
     * @param mobile
     * @param password
     * @param name
     * @param identifyCode
     * @param merchantCode
     * @param auth
     * @param user
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveManager(String mobile, String password, String name, String identifyCode, String merchantCode,
                            String auth, SysUserEntity user) {

        boolean flag = sMSService.checkAuthCode(mobile, identifyCode, Constants.MESSAGE_TYPE_REGISTER);
        if (!flag) {
            throw new BusinessException("验证码验证失败!");
        }

        Long roleId = Constants.ROLE_ID_WAITER;

        if (String.valueOf(Constants.ROLE_ID_STOREADMIN).equals(auth)) {

            //验证门店高管数量
            String storeId = user.getCurrentStoreId();
            List<SysUserEntity> userList = sysUserMapper.queryListByStoreId(storeId);
            for (SysUserEntity sysUserEntity : userList) {
                List<Long> roleIdList = sysUserRoleService.queryRoleIdList(sysUserEntity.getUserId());
                if (roleIdList.contains(Constants.ROLE_ID_STOREADMIN)) {
                    throw new BusinessException("门店已经有一个高管啦!");
                }
            }

            flag = sMSService.checkAuthCode(user.getMobile(), merchantCode, Constants.MESSAGE_TYPE_OTHER);
            if (!flag) {
                throw new BusinessException("商家验证码验证失败!");
            }
            roleId = Constants.ROLE_ID_STOREADMIN;
        }

        SysUserEntity sysUser = new SysUserEntity();
        //sha256加密
        String salt = RandomStringUtils.randomAlphanumeric(20);
        sysUser.setSalt(salt);
        sysUser.setPassword(new Sha256Hash(password, salt).toHex());
        sysUser.setMobile(mobile);
        sysUser.setUsername(mobile);
        sysUser.setName(name);
        sysUser.setCreateUserId(user.getUserId());
        sysUser.setCurrentStoreId(user.getCurrentStoreId());
        sysUser.setCreateTime(new Date());
        sysUser.setStatus(1);
        List<Long> list = new ArrayList(1);
        list.add(Long.parseLong(auth));
        sysUser.setRoleIdList(list);
        sysUserMapper.insertSelective(sysUser);
        Long userId = sysUserMapper.selectByMobile(mobile).getUserId();
        sysUser.setUserId(userId);
        //检查角色是否越权
        checkRoleAPP(sysUser);

        //保存用户与角色关系
        sysUserRoleService.saveOrUpdate(sysUser.getUserId(), sysUser.getRoleIdList());

        //保存门店与用户之间关系
        UserStore userStore = new UserStore();
        userStore.setId(IdWorkerFactory.nextId());
        userStore.setUserId(userId);
        userStore.setUserName(mobile);
        userStore.setName(name);
        userStore.setStoreId(Long.parseLong(user.getCurrentStoreId()));
        userStore.setMobile(mobile);
        userStore.setRoleId(roleId);
        userStore.setInsertByUserName(user.getUsername());
        userStore.setInsertDate(new Date());
        userStoreMapper.insert(userStore);
    }

    /**
     * 解绑管理员
     *
     * @param user
     * @param userId
     * @return
     */
    @Override
    @Transactional
    public ReturnResult freeManager(SysUserEntity user, String userId) {
        Long userIdL = Long.parseLong(userId);
        List<Long> managerRoleIdList = sysUserRoleService.queryRoleIdList(user.getUserId());
        List<Long> roleIdList = sysUserRoleService.queryRoleIdList(userIdL);

        //取消高级管理员
        if (roleIdList.size() > 0 && managerRoleIdList.size() > 0 && roleIdList.contains(Constants.ROLE_ID_STOREADMIN)
                && managerRoleIdList.contains(Constants.ROLE_ID_MERCHANT)) {
            free(userIdL);
            return ReturnResult.ok();
        }

        //取消普通服务员
        if (roleIdList.size() > 0 && managerRoleIdList.size() > 0 && roleIdList.contains(Constants.ROLE_ID_WAITER)
                && (managerRoleIdList.contains(Constants.ROLE_ID_MERCHANT) || managerRoleIdList.contains(Constants.ROLE_ID_STOREADMIN))) {
            free(userIdL);
            return ReturnResult.ok();
        }

        userStoreMapper.deleteByStoreIdAndUserId(userId, user.getCurrentStoreId());

        return ReturnResult.error("权限不足!");
    }

    /**
     * 管理员列表
     *
     * @return
     */
    @Override
    public ReturnResult managerList(Map<String, Object> params) {

        Query query = new Query(params);
        int i = userStoreMapper.queryTotal(query);
        List<UserStore> userStores = null;
        if (i > 0) {
            userStores = userStoreMapper.queryList(query);
        }
        PageUtils pageUtils = new PageUtils(userStores, i, query.getLimit(), query.getPage());
        return ReturnResult.ok().put("page",pageUtils);
    }

    /**
     * 解除绑定
     */
    public void free(Long userIdL) {
        int j = sysUserRoleService.deleteByuserId(userIdL);
        SysUserEntity userEntity = new SysUserEntity();
        userEntity.setUserId(userIdL);
        userEntity.setDelFlag(Constants.DELETE_FLAG_UNABLE);
        int i = sysUserMapper.updateByPrimaryKeySelective(userEntity);
        sysUserTokenService.deleteToken(userIdL);
        if (i == 0 || j == 0) {
            throw new BusinessException(" 解除失败!");
        }
    }


    /**
     * 校验app创建高管和点餐员
     *
     * @param sysUser
     */
    private void checkRoleAPP(SysUserEntity sysUser) {

        List<Long> roleIdList = sysUserRoleService.queryRoleIdList(sysUser.getCreateUserId());
        List<Long> roleId = sysUser.getRoleIdList();
        if (roleId.contains(Constants.ROLE_ID_STOREADMIN) && !roleIdList.contains(Constants.ROLE_ID_MERCHANT)) {
            throw new BusinessException("门店高管必须由商家创建!");
        }
    }

}
